package com.ztc.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ztc.bean.ProjectModel;
import com.ztc.bean.ReportHistoryModel;
import com.ztc.bean.ReportModel;
import com.ztc.costants.Constants;
import com.ztc.service.ReportService;
import com.ztc.util.AsposeWordUtil;
import com.ztc.util.DateUtil;
import com.ztc.util.RichHtmlHandler;
import com.ztc.util.WordGeneratorWithFreemarker;

/**
 * @类名：ReportController.java
 * @作者：李晓平
 * @时间：2018年7月25日 下午2:03:51
 * @描述：报告、说明管理控制类
 */
@CrossOrigin
@RestController
public class ReportController {
	private Logger logger = Logger.getLogger(ReportController.class);
	
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
	private SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMddHHmmss");
	
	@Autowired
	private ReportService reportService;	

	/**
	 * 查询单项报告内容
	 * @param authId
	 * @param relation
	 * @param projectId
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/queryReportContent")
	public Map<String, Object> queryReportContent(Integer authId, String relation, Integer projectId) throws Exception{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(authId == null) {
				throw new IllegalArgumentException("请输入权限信息");
			}
			if(StringUtils.isBlank(relation)) {
				throw new IllegalArgumentException("请输入目标表");
			}
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目信息");
			}
			ReportModel report = reportService.queryReportContent(authId, relation, projectId);
			resultMap.put("result", report);
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，查询内容失败";
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 查询单项报告内容
	 * @param authId
	 * @param relation
	 * @param projectId
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/queryReportTemplate")
	public Map<String, Object> queryReportTemplate(Integer authId, Integer projectId) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(authId == null) {
				throw new IllegalArgumentException("请输入权限信息");
			}
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目信息");
			}
			ReportModel report = reportService.queryReportTemplate(authId, projectId);
			resultMap.put("result", report);
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，查询模板失败";
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 保存内容
	 * @param reportModel
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/saveReportContent")
	public Map<String, Object> saveReportContent(ReportModel reportModel) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			ReportModel model = reportService.saveReportContent(reportModel);
			resultMap.put("contentId", model.getContentId());
			resultMap.put("updateTime", sdf.format(model.getUpdateTime()));
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，保存内容失败";
//			message = CommonException.getMessage(e, message);
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 查询历史版本
	 * @param relation
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/queryVersionList")
	public Map<String, Object> queryVersionList(String relation, Integer projectId) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(StringUtils.isBlank(relation)) {
				throw new IllegalArgumentException("请输入目标表");
			}
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目ID");
			}
			List<String> versionList = reportService.queryHistoryList(relation, projectId);
			resultMap.put("resultList", versionList);
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，查询历史版本失败";
//			message = CommonException.getMessage(e, message);
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 查询历史版本内容
	 * @param authId
	 * @param relation
	 * @param projectId
	 * @param version
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/queryCompareContent")
	public Map<String, Object> queryCompareContent(Integer authId, String relation, Integer projectId, String version) throws Exception{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(authId == null) {
				throw new IllegalArgumentException("请输入权限信息");
			}
			if(StringUtils.isBlank(relation)) {
				throw new IllegalArgumentException("请输入目标表");
			}
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目信息");
			}
			if(StringUtils.isBlank(version)) {
				throw new IllegalArgumentException("请输入版本号");
			}
			ReportModel report = reportService.queryReportContent(authId, relation, projectId);
			ReportHistoryModel reportHistory = reportService.queryVersionContent(relation, projectId, version);
			resultMap.put("historyVersionContent", reportHistory.getContent());
			resultMap.put("lastVersionContent", report.getContent());
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，查询历史版本内容失败";
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	
	/**
	 * 保存是否导出
	 * @param projectId
	 * @param isExport
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/saveIsExport")
	public Map<String, Object> saveIsExport(ReportModel reportModel) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			ReportModel model = reportService.saveIsExport(reportModel);
			resultMap.put("contentId", model.getContentId());
			resultMap.put("updateTime", sdf.format(model.getUpdateTime()));
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，保存是否导出失败";
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 查询全部报告内容
	 * @param projectId
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/queryAllReportContent")
	public Map<String, Object> queryAllReportContent(Integer projectId) throws Exception{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目ID");
			}
			String content = reportService.queryAllReportContent(projectId, 1);
			ReportModel report = new ReportModel();
			report.setContent(content);
			resultMap.put("result", report);
		} catch (IllegalArgumentException ie) {
			throw ie;
		} catch (Exception e) {
			message = "未知异常，查询全部报告内容失败";
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 查询全部说明内容
	 * @param projectId
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/queryAllDescriptionContent")
	public Map<String, Object> queryAllDescriptionContent(Integer projectId) throws Exception{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目ID");
			}
			String content = reportService.queryAllReportContent(projectId, 2);
			ReportModel report = new ReportModel();
			report.setContent(content);
			resultMap.put("result", report);
		} catch (IllegalArgumentException ie) {
			throw ie;
		} catch (Exception e) {
			message = "未知异常，查询全部说明内容失败";
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	

	
	/**
	 * 查找
	 * @param projectId
	 * @param keyword
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/findContent")
	public Map<String, Object> findContent(Integer projectId, Integer type, String keyword) throws Exception{
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目ID");
			}
			if(StringUtils.isBlank(keyword)) {
				throw new IllegalArgumentException("请输入要查找的内容");
			}
			if(type == null) {
				type = 1;
			}
			List<Map<String, Object>> resultList = reportService.findContent(projectId, type, keyword);
			resultMap.put("result", resultList);
		} catch (IllegalArgumentException ie) {
			throw ie;
		} catch (Exception e) {
			message = "未知异常，查找失败";
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 导出报告
	 * @param projectId
	 * @param isExport
	 * @return
	 * @throws Exception 
	 */
	@Deprecated
	@RequestMapping("/exportReport")
	public Map<String, Object> exportReport(HttpServletRequest request, HttpServletResponse response, Integer projectId) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目ID");
			}
			ProjectModel project = reportService.queryProjectById(projectId);
			//获取富文本html
			StringBuilder richHtml = reportService.generateReportHtml(project);
			//处理富文本html
			RichHtmlHandler handler = new RichHtmlHandler(richHtml.toString());
			handler.setDocSrcLocationPrex("file:///C:/213792E5");
			handler.setDocSrcParent("report_template.files");
			handler.setNextPartId("01D412E2.F9A3AFB0");
			handler.setShapeidPrex("_x56fe__x7247__x0020");
			handler.setSpidPrex("_x0000_i");
			handler.setTypeid("#_x0000_t75");
			handler.handledHtml(false);

			Map<String, Object> data = new HashMap<String, Object>();
			String bodyBlock = handler.getHandledDocBodyBlock();
//			System.out.println("bodyBlock:\n"+bodyBlock);

			String handledBase64Block = "";
			if (handler.getDocBase64BlockResults() != null
					&& handler.getDocBase64BlockResults().size() > 0) {
				for (String item : handler.getDocBase64BlockResults()) {
					handledBase64Block += item + "\n";
				}
			}
			data.put("imagesBase64String", handledBase64Block);

			String xmlimaHref = "";
			if (handler.getXmlImgRefs() != null
					&& handler.getXmlImgRefs().size() > 0) {
				for (String item : handler.getXmlImgRefs()) {
					xmlimaHref += item + "\n";
				}
			}
			data.put("imagesXmlHrefString", xmlimaHref);
			data.put("content", bodyBlock);
			data.put("projectName", project.getProjectName());
			data.put("reportNo", project.getReportNo());
			data.put("reportDate", DateUtil.getUpperDate(sdf2.format(new Date())));
			
			response.reset();
			response.setHeader("Content-disposition", "attachment; filename=" 
					+ URLEncoder.encode(project.getProjectName() + "_" + sdf3.format(new Date()) + ".doc", "utf-8"));
			response.setContentType("application/msword");
			response.setCharacterEncoding("utf-8");
			OutputStream output=response.getOutputStream();
			WordGeneratorWithFreemarker.createDoc(data, "report_template.ftl", output);
			output.close();
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，导出报告失败";
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	
	/**
	 * 导出报告，poi方式
	 * @param projectId
	 * @param isExport
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/exportReportByPoi")
	public Map<String, Object> exportReportByPoi(HttpServletRequest request, HttpServletResponse response, Integer projectId) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目ID");
			}
			resultMap.putAll(exportReport(request, projectId, Constants.AuthType_Report));
			//exportReport(response, projectId, Constants.AuthType_Report);
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
//			success = false;
			message = "未知异常，导出资产评估报告失败";
//			message = CommonException.getMessage(e, message);
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 导出资产评估说明，poi方式
	 * @param projectId
	 * @param isExport
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping("/exportDescriptionByPoi")
	public Map<String, Object> exportDescriptionByPoi(HttpServletRequest request, HttpServletResponse response, Integer projectId) throws Exception {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			if(projectId == null) {
				throw new IllegalArgumentException("请输入项目ID");
			}

			resultMap.putAll(exportReport(request, projectId, Constants.AuthType_Description));
//			exportReport(response, projectId, Constants.AuthType_Description);
		} catch (IllegalArgumentException ie) {
//			success = false;
//			message = ie.getMessage();
//			logger.error(message, ie);
			throw ie;
		} catch (Exception e) {
			e.printStackTrace();
//			success = false;
			message = "未知异常，导出资产评估说明失败";
//			message = CommonException.getMessage(e, message);
//			logger.error(message, e);
			throw new Exception(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	private Map<String, Object> exportReport(HttpServletRequest request, int projectId, int type) throws Exception {
		ProjectModel project = reportService.queryProjectById(projectId);
//		if(StringUtils.isBlank(project.getFinalMethod())) {
//			throw new IllegalArgumentException("请先设置最终评估方法");
//		}
		
		XWPFDocument doc = new XWPFDocument();
		
		String marningMsgStr = reportService.generateReportHtmlByPoi(doc, project, type);
		
		//保存文件，临时文件，用完删掉
		String reportName = "";
		switch (type) {
			case 1:
				reportName = "资产评估报告";
				break;
			case 2:
				reportName = "资产评估说明";
				break;
		}
		String fileName = reportName + "-" + project.getEvaluateTarget() + "_" + sdf3.format(new Date()) + ".docx";
//		String fileStorePath = GlobalUtil.getGlobalParam("fileStorePath");
//		String fileStorePath = request.getSession().getServletContext().getRealPath("/");
//		File file = new File(fileStorePath);
//		if(!file.exists()) {
//			file.mkdir();
//		}
		File file = new File(fileName);
		String filePath = file.getAbsolutePath();
		filePath = filePath.replace("\\", "/");
//		String filePath = fileStorePath + "/" + fileName;
		FileOutputStream fos = new FileOutputStream(file);
		doc.write(fos);
		fos.flush();
		fos.close();
		doc.close();
//		file = new File(filePath);
//		while(!file.exists()) {
//			file = new File(filePath);
//		}
		// 生成目录
		try {
			AsposeWordUtil.regenFile(filePath);
		} catch (Exception e) {
			e.printStackTrace();
			throw new IllegalArgumentException("导出失败，请稍后重试");
		}
		
		file = new File(filePath);
		InputStream is = new FileInputStream(file);
		XWPFDocument doc2 = new XWPFDocument(is);
		doc2.enforceUpdateFields();
		FileOutputStream fos2 = new FileOutputStream(file);
		doc2.write(fos2);
		fos.flush();
		fos.close();
		doc2.close();
		
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("downloadFilePath", filePath);
		map.put("marningMsg", marningMsgStr);
		return map;
	}
	
	/**
	 * 导出报告、说明
	 * @param response
	 * @param projectId
	 * @param type
	 * @throws Exception
	 */
	@Deprecated
	private void exportReport(HttpServletRequest request, HttpServletResponse response, int projectId, int type) throws Exception {
		ProjectModel project = reportService.queryProjectById(projectId);
		XWPFDocument doc = new XWPFDocument();
		
		reportService.generateReportHtmlByPoi(doc, project, type);
		
		//保存文件，临时文件，用完删掉
		String reportName = "";
		switch (type) {
			case 1:
				reportName = "资产评估报告";
				break;
			case 2:
				reportName = "资产评估说明";
				break;
		}
		String fileName = reportName + "-" + project.getEvaluateTarget() + "_" + sdf3.format(new Date()) + ".doc";
//		String fileStorePath = GlobalUtil.getGlobalParam("fileStorePath");
		String fileStorePath = request.getSession().getServletContext().getRealPath("/");
		File file = new File(fileStorePath);
		if(!file.exists()) {
			file.mkdir();
		}
		String filePath = fileStorePath + "/" + fileName;
		FileOutputStream fos = new FileOutputStream(filePath);
		doc.write(fos);
		fos.flush();
		fos.close();
		
		file = new File(filePath);
		while(!file.exists()) {
			file = new File(filePath);
		}
		//生成目录
		AsposeWordUtil.generateCatalog(filePath, type);
		
		response.reset();
		response.setHeader("Content-disposition", "attachment; filename=" 
				+ URLEncoder.encode(fileName, "utf-8"));
		response.setContentType("application/octet-stream");
		response.setCharacterEncoding("utf-8");
		
		InputStream inputStream = new FileInputStream(file);
		OutputStream os = response.getOutputStream();
		byte[] b = new byte[1024];
		int length;
		while ((length = inputStream.read(b)) > 0) {
			os.write(b, 0, length);
		}
		inputStream.close();
		os.flush();
		os.close();
		file.delete();
	}
	

	
	/**
	 * 修改表格 增加一列
	 * @return·
	 */
	@RequestMapping("/alterTable")
	public Map<String, Object> alterTable() {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			reportService.alterTable();
		} catch (Exception e) {
			success = false;
			message = "未知异常，修改表格增加一列失败";
			logger.error(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
	
	/**
	 * 处理报告、说明内容，去掉html标签，获取纯文本
	 * @return·
	 */
	@RequestMapping("/dealData")
	public Map<String, Object> dealData() {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		boolean success = true;
		String message = "";
		try {
			reportService.dealData();
		} catch (Exception e) {
			success = false;
			message = "未知异常，获取纯文本失败";
			logger.error(message, e);
		}
		resultMap.put("success", success);
		resultMap.put("message", message);
		
		return resultMap;
	}
}
